package com.hertz.appr.service.cmd.v1;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.hertz.appr.pojo.CmdPojo;
import com.hertz.appr.pojo.db.Action;
import com.hertz.appr.pojo.db.Answer;
import com.hertz.appr.pojo.db.Message;
import com.hertz.appr.service.ActionService;
import com.hertz.appr.service.AnswerService;
import com.hertz.appr.service.MemberService;
import com.hertz.appr.service.MessageService;
import com.hertz.appr.service.TaskService;
import com.hertz.appr.util.CmdHelper;
import com.hertz.appr.util.Util;
import com.hertz.appr.util.WeiboException;

public class CmdPojoFactory implements ICmdPojoFactory {

	private Logger log = Logger.getLogger(CmdPojoFactory.class);
	private ActionService actionService;
	private TaskService taskService;
	private MemberService memberService;
	private AnswerService answerService;
//	private boolean anonym;//是否允许匿名使用命令
	private boolean checkMember = true;
	private MessageService messageService;
	private Map<Short, ICmdLineService> cmdLineServiceMap;
	
	private List<ICmdLineService> cmdLineServiceList;
	
	
	public void init(){
		cmdLineServiceMap = new HashMap<Short, ICmdLineService>();
		for(ICmdLineService cmdLineService : cmdLineServiceList){
			cmdLineServiceMap.put(cmdLineService.getCmdType(), cmdLineService);
		}
	}
	
	@Override
	public CmdPojo buildCmdPojo(Message msg) {
		log.debug("start buildCmdPojo");
		if(msg == null || StringUtils.isBlank(msg.getOrigtext())){
			log.debug("no message");
			return null;
		}
		String cmdLine = getCmdLine(msg.getOrigtext());
		CmdPojo cmdPojo = buildCmdPojo(cmdLine);
		Action action = null;
		if(msg.getSourceTwitter() != null){
			action = actionService.getAction(msg.getSourceTwitter());
		}
		if(action != null){
//			cmdPojo.setAidStr(ActionService.getActionId62Hex(action.getId()));
			cmdPojo.setAid(action.getId());
		}
		
		if(cmdPojo != null && !cmdPojo.getRes().equals("ok")){
			taskService.buildWarningTask(msg,checkMember,"tempname.warning.cmd." + cmdPojo.getType(), null);
			return null;
		}else{//buildCmdPojo 返回 ok,校验参数值
			if(msg.getType().equals(Message.type_original)){//是原创微博
				if(cmdPojo.getType() == CmdPojo.cmdType_respond){//不是guess,promote,action命令，返回null
					log.info("is original Twitter,cmdType = respond ,return null");
					return null;
				}else if(cmdPojo.getType() == CmdPojo.cmdType_action){//是action 命令，返回null
					log.info("is original Twitter,but cmdType = update ,return null");
					return null;
				}else{//可能是promote 或 guess
					ICmdLineService cmdLineService = cmdLineServiceMap.get(cmdPojo.getType());
					if(cmdLineService == null){//没有匹配的cmdLineService
						log.error("no match cmdLineService,return null,cmdType=" + cmdPojo.getType());
						return null;
					}else{
						String result = cmdLineService.checkCommandLine(cmdPojo.getCl());
						if(StringUtils.isNotBlank(result) && result.equals("ok")){
							log.info("check cmdLineService ok,return this cmdPojo");
							return cmdPojo;
						}else{
							taskService.buildWarningTask(msg, checkMember, "tempname.warning.cmd." + cmdPojo.getType(), null);
							return null;
						}
					}
				}
			}else if(msg.getType().equals(Message.type_comment) || msg.getType().equals(Message.type_repost)){//评论或转发微博
				if(cmdPojo.getType() == CmdPojo.cmdType_respond){//
					if(action == null){//
						log.info("action is null,return null");
						return null;
					}else if(msg.getUid().equals(action.getUid())){//活动发起者不能参与活动
						log.info("活动发起者不能参与活动，return null");
						return null;
					}else if(!action.getStatus().equals(Action.ACTION_STATUS_START)){
						log.info("action is unstart,return null");//非激活状态的活动，不统计
						return null;
					}else if(action.getEndTime() != null && msg.getCreateTime() > action.getEndTime()){//大于自动结束时间,返回null,更新action
						log.info("msg.createTime > action.endTime,update action,return null");
						if(action.getType().equals(Action.ACTION_TYPE_GUESS)){
							action.setStatus(Action.ACTION_STATUS_END);
						}else{
							action.setStatus(Action.ACTION_STATUS_WAITDEAL);
						}
						action.setSystemTime(System.currentTimeMillis());
						actionService.updateAction(action);
						return null;
					}else{
						return cmdPojo;
					}
				}else if(cmdPojo.getType() == CmdPojo.cmdType_action){
					if(action == null){
						log.info("action is unstart,return null");
						return null;
					}
					if(!msg.getUid().equals(action.getUid()) || !msg.getProvider().equals(action.getProvider())){
						log.info("no privilege");
						return null;
					}else{
						ICmdLineService cmdLineService = cmdLineServiceMap.get(cmdPojo.getType());
						if(cmdLineService == null){//没有匹配的cmdLineService
							log.error("no match cmdLineService,return null,cmdType=" + cmdPojo.getType());
							return null;
						}else{
							String result = cmdLineService.checkCommandLine(cmdPojo.getCl());
							if(StringUtils.isNotBlank(result) && result.equals("ok")){
								log.info("check cmdLineService ok,return this cmdPojo");
								if(cmdPojo.getCl().hasOption(ICmdLineService.oAnswer) && !action.getType().equals(Action.ACTION_TYPE_GUESS)){
									taskService.buildWarningTask(msg, checkMember, "tempname.warning", null);
									return null;
								}else{
									return cmdPojo;
								}
							}else{
								taskService.buildWarningTask(msg, checkMember, "tempname.warning", null);
								return null;
							}
						}
					}
				}else{
//					taskService.buildWarningTask(msg, checkMember, "tempname.warning.cmd." + cmdPojo.getType(), "@" + msg.getUid() + " 请通过发表原创微博，发起一个活动");
					log.info("非原创微博，不能发起活动，return null");
					return null;
				}
				
			}else{
				log.info("仅支持原创，评论，转发三种形式的微博");
				return null;
			}
		}
	}

	@Override
	public CmdPojo buildCmdPojo(String cmdLine) {
		CmdPojo cmdPojo = new CmdPojo();
		log.info("cmdLine : " + cmdLine);
		if(StringUtils.isBlank(cmdLine)){
			log.debug("no cmdLine,may be respond promote");
			cmdPojo.setRes("ok");
			cmdPojo.setType(CmdPojo.cmdType_respond);
			return cmdPojo;
		}else{
			for(ICmdLineService cmdLineService : cmdLineServiceList){
				log.info("is " + cmdLineService);
				if(cmdLineService.isCmdLine(cmdLine)){
					CommandLine cl = null;
					String res = "";
					try {
						if((cmdLineService.getCmdType().equals(CmdPojo.cmdType_guess) || cmdLineService.getCmdType().equals(CmdPojo.cmdType_promote)) && cmdLine.trim().split(" ").length < 2){
							cmdLine = cmdLine + " -c=1";
						}
						cl = cmdLineService.buildCmdLine(cmdLine);
						res = "ok";
					} catch (Exception e) {
						// TODO: handle exception
						res = "error:" + e.getMessage();
					}
					cmdPojo.setCl(cl);
					cmdPojo.setCmdText(cmdLine);
					cmdPojo.setRes(res);
					cmdPojo.setType(cmdLineService.getCmdType());
					return cmdPojo;
				}
			}
			//可能是活动的回复，若是推广型的活动，则不分析<>中的内容。
			log.info("may be respond");
			cmdPojo.setCmdText(cmdLine);
			cmdPojo.setRes("ok");
			cmdPojo.setType(CmdPojo.cmdType_respond);
			return cmdPojo;
		}
	}

	@Override
	public void dealMessage(Message msg, CmdPojo cmdPojo) {
		// TODO Auto-generated method stub
		if(cmdPojo.getType() == CmdPojo.cmdType_action){
			if(isCheckMember()){
				if(memberService.hasPrivilege(msg.getUid(), msg.getProvider())){
					updateAction(msg, cmdPojo);
				}
			}
			
		}else if(cmdPojo.getType() == CmdPojo.cmdType_guess || cmdPojo.getType() == CmdPojo.cmdType_promote){//生成新活动
			if(isCheckMember()){
				if(memberService.hasPrivilege(msg.getUid(), msg.getProvider())){
					newAction(msg, cmdPojo);
				}
			}
		}else{
			newMessage(msg,cmdPojo);
		}
	}
	
	private void newMessage(Message msg,CmdPojo cmdPojo){
		long currentTime = System.currentTimeMillis();
		if(msg.getSourceTwitter() == null){
			log.error("非转播或评论的微博,不参与抽奖");
			return;
		}
		msg.setActionId(cmdPojo.getAid());
		msg.setSystemTime(currentTime);
		msg.setValue(cmdPojo.getCmdText());
		messageService.save(msg);
		log.debug("save " + msg);
	}
	
	private void updateAction(Message msg,CmdPojo cmdPojo){
		if(cmdPojo.getType() != CmdPojo.cmdType_action){
			log.error("not action cmd,return");
			return;
		}
		Action action = actionService.getAction(cmdPojo.getAid());
		if(action == null){
			log.error("no action");
			return;
		}
		if(cmdPojo.getCl().hasOption(ICmdLineService.oEnd)){
			if(action.getType().equals(Action.ACTION_TYPE_PROMOTE)){
				action.setStatus(Action.ACTION_STATUS_WAITDEAL);
			}else{
				action.setStatus(Action.ACTION_STATUS_END);
			}
			action.setEndTime(msg.getCreateTime());
			action.setSystemTime(System.currentTimeMillis());
			actionService.updateAction(action);
			log.info("update " + action);
			taskService.buildNoticeTask(msg, action);
		}else if(cmdPojo.getCl().hasOption(ICmdLineService.oAnswer)){
			
			log.debug("give action answer");
			if(action.getStatus() < Action.ACTION_STATUS_WAITDEAL){
				if(action.getType().equals(Action.ACTION_TYPE_PROMOTE)){
					log.error("this action's type is promote,needn't answer");
					log.debug(msg);
					return;
				}else if(action.getType().equals(Action.ACTION_TYPE_GUESS)){
					Answer answer = new Answer();
					answer.setActionId(action.getId());
					answer.setCreateTime(System.currentTimeMillis());
					answer.setNick(msg.getNick());
					answer.setOrigtext(msg.getOrigtext());
					answer.setProvider(msg.getProvider());
					answer.setSystemTime(System.currentTimeMillis());
					answer.setTid(msg.getTid());
					answer.setUid(msg.getUid());
					answer.setValue(cmdPojo.getCl().getOptionValue(ICmdLineService.oAnswer));
					answerService.saveAnswer(answer);
					log.debug("save " + answer);
				}
				action.setEndTime(msg.getCreateTime());
				action.setSystemTime(System.currentTimeMillis());
				action.setStatus(Action.ACTION_STATUS_WAITDEAL);
				actionService.updateAction(action);
				log.info("update " + action);
				taskService.buildNoticeTask(msg, action);
				
			}
		}
	}
	
	private void newAction(Message msg,CmdPojo cmdPojo){
		Long currentTime = System.currentTimeMillis();
		Action action = new Action();
		String endTime = cmdPojo.getCl().getOptionValue(ICmdLineService.oEndtime);
		if(StringUtils.isNotBlank(endTime)){
			String format = "";
			if(endTime.matches(CmdHelper.endtime_regex)){
				format = "yyyyMMdd-HH:mm:ss";
			}else if(endTime.matches(CmdHelper.endtime_ymd_regex)){
				format = "yyyyMMdd";
			}else{
				log.error("guess -et format error,-et=" + endTime);
				taskService.buildWarningTask(msg);
				return;
			}
			try {
				Date date = Util.parseDate(endTime, format);
				action.setEndTime(date.getTime());
			} catch (WeiboException e) {
				// TODO Auto-generated catch block
				log.error("guess -et format error,-et=" + endTime);
				e.printStackTrace();
				taskService.buildWarningTask(msg);
				return;
			}
			
		}
		action.setCreateTime(currentTime);
		action.setNick(msg.getNick());
		action.setRegText(msg.getOrigtext());
		action.setProvider(msg.getProvider());
		action.setStartTime(msg.getCreateTime());
		action.setStatus(Action.ACTION_STATUS_START);
		action.setSystemTime(currentTime);
		action.setRegTid(msg.getTid());
		if(cmdPojo.getType() == CmdPojo.cmdType_guess)
			action.setType(Action.ACTION_TYPE_GUESS);
		else if(cmdPojo.getType() == CmdPojo.cmdType_promote)
			action.setType(Action.ACTION_TYPE_PROMOTE);
		action.setUid(msg.getUid());
		action.setValue(cmdPojo.getCmdText());
		actionService.saveAction(action);
		log.debug("save action ok");
		
		taskService.buildNoticeTask(msg, action);
	}
	
	/**
	 * 返回命令行，去空格，去<>，只返回第一个<>中的内容
	 * @param msgText
	 * @return
	 */
	public String getCmdLine(String msgText){
		Pattern pBrackets = CmdHelper.pCmdLine;
		Matcher mBrackets = pBrackets.matcher(msgText);
		String cmd = "";
		int i = 0;
		while(mBrackets.find()){
			if(i != 0)
//				cmd = cmd + ",";
				break;//只分析第一个<>中的内容
			cmd = cmd + mBrackets.group(1);
			i++;
		}
		return cmd;
	}

	public ActionService getActionService() {
		return actionService;
	}

	public void setActionService(ActionService actionService) {
		this.actionService = actionService;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public MemberService getMemberService() {
		return memberService;
	}

	public void setMemberService(MemberService memberService) {
		this.memberService = memberService;
	}

	public AnswerService getAnswerService() {
		return answerService;
	}

	public void setAnswerService(AnswerService answerService) {
		this.answerService = answerService;
	}

	public boolean isCheckMember() {
		return checkMember;
	}

	public void setCheckMember(boolean checkMember) {
		this.checkMember = checkMember;
	}

	public List<ICmdLineService> getCmdLineServiceList() {
		return cmdLineServiceList;
	}

	public void setCmdLineServiceList(List<ICmdLineService> cmdLineServiceList) {
		this.cmdLineServiceList = cmdLineServiceList;
	}

	public MessageService getMessageService() {
		return messageService;
	}

	public void setMessageService(MessageService messageService) {
		this.messageService = messageService;
	}
	
}
